home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
BBS-Archive
/
Comm
/
AmiTCP30b2.lha
/
src
/
appl
/
napsaterm
/
napsaprefs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-19
|
17KB
|
747 lines
RCS_ID_C="$Id: napsaprefs.c,v 3.9 1994/05/18 15:09:54 ppessi Exp $";
/*
* napsaprefs.c --- preferences for napsaterm
*
* Author: ppessi <Pekka.Pessi@hut.fi>
*
* Copyright (c) 1993 Pekka Pessi
*
* Created : Sun Nov 7 08:27:25 1993 ppessi
* Last modified: Wed May 18 18:08:55 1994 ppessi
*
* $Log: napsaprefs.c,v $
* Revision 3.9 1994/05/18 15:09:54 ppessi
* Changed default ctrl8bit tool type to ctrl8bit=no
*
* Revision 3.8 1994/05/14 12:49:00 ppessi
* Multicharacter options are now preceded with double hyphen.
* Added "Control Codes" (7/8 bit) entry into "Setup" menu.
*
* Revision 3.7 1994/05/11 12:53:42 ppessi
* Merged changes from Napsaterm 3.5 by R. Knop
*
* Revision 3.6 1994/02/25 16:08:03 ppessi
* Fixed a bug in the national setting (only Danish and US could be selected)
*
* Revision 3.5 1994/02/25 02:33:38 ppessi
* Added RCS ID
*
* Revision 3.4 1994/02/25 02:00:48 ppessi
* Reverted back to S:Napsaprefs preference file
*
* Revision 3.3 1994/01/16 18:21:15 ppessi
* No perrorparse() printouts
*
* Revision 3.2 94/01/08 08:54:52 ppessi
* Enabled switch tool types; added support to different program names
*
* Revision 3.1 94/01/07 22:51:25 ppessi
* Version 3 beta
*
* Revision 2.1 93/11/18 18:34:12 ppessi
* Changed menu format.
*
* Revision 2.0 93/11/15 03:38:53 ppessi
* Version 2 initial revision
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "nifty.h"
#include "amiga.h"
#include "napsaprefs.h"
#include "display.h"
#include "dispmacros.h"
#include "wimp.h"
#include <workbench/workbench.h>
#include <workbench/startup.h>
#if USE_PRAGMAS
#include <proto/icon.h>
#endif
#if USE_INLINE
#include <inline/icon.h>
#endif
#if USE_CLIB
#include <clib/icon_protos.h>
#endif
#define PREFSFILE \
"AmiTCP:db/NapsaPrefs" NUL "s:NapsaPrefs" NUL "s:NiftyPrefs" NUL
/*
* Hosts to connect
*/
#define MAXHOSTS 63 /* you can specify only 63 hosts */
int hostc;
char *hostarray[MAXHOSTS + 1];
static void addhost(char *newhost, void *dummy);
struct napsaprefs np;
struct parsing {
char p_type;
char p_slen; /* significant length */
ushort p_offset;
union {
const char *pu_option;
const char *pu_values;
int (*pu_func)(char *, void *);
} p;
char *p_resource;
long p_default;
};
#define p_option p.pu_option
#define p_values p.pu_values
#define p_func p.pu_func
#define T_END 0
#define T_STRING 1
#define T_FLAG 2 /* true/false */
#define T_TOGGLE 3 /* option will toggle the default */
#define T_NUMBER 4
#define T_SPECIAL 5
#define T_ENUM 6
#define OFFSET_OF(x) ((ushort)&((struct napsaprefs *)NULL)->x)
#define LPARSE(type, what, optnam, resource, default) \
{type,2,OFFSET_OF(what),optnam,resource,(long)default}
#define PARSE(type, what, optnam, resource, default) \
{type,sizeof(optnam)-1,OFFSET_OF(what),optnam,resource,(long)default}
#define PENUM(what, resource, values, default, len) \
{T_ENUM,len,OFFSET_OF(what),values,resource,(long)default}
#define PRESET(type, what, resource, default) \
{type,0,OFFSET_OF(what),NULL,resource,(long)default}
#define PSPECIAL(what, resource, function) \
{T_SPECIAL, 0, OFFSET_OF(what), (void *)function, resource, 0}
#define NP_ADDR(offset) (void*)((char*)&np + offset)
extern char nation_names[];
static char national_names[] =
"None" NUL "Multinational" NUL "National" NUL;
static char bell_names[] =
"None" NUL "Visual" NUL "Audio" NUL "Both" NUL "Display" NUL;
static char cursor_names[] =
"Underlined" NUL "Block" NUL "Invisible" NUL;
static char sizing_names[] =
"None" NUL "Column" NUL "Row" NUL;
static char emulation_names[] =
"vt102" NUL "vt52" NUL "h19" NUL;
static char mouse_names[] =
"Off" NUL "Down" NUL "Up" NUL "Both" NUL;
/* Added RKNOP 940328 */
static char keypad_names[] =
"Numeric" NUL "Application" NUL;
/* End added RKNOP */
static const struct parsing presets[] =
{
PARSE(T_STRING, logname, "l", NULL, NULL),
PARSE(T_FLAG, show_version, "V", NULL, 1),
PARSE(T_TOGGLE, wait_to_end, "w", "WAITTOEND", 0),
/* emulation mode */
PENUM(emulation, "EMULATION", emulation_names, EMU_VT102, 3),
PARSE(T_FLAG, emulation, "-vt102", NULL, EMU_VT102),
PARSE(T_FLAG, emulation, "-vt52", NULL, EMU_VT52),
PARSE(T_FLAG, emulation, "-h19", NULL, EMU_H19),
PENUM(national, "NATIONAL", national_names, 0, 2),
/* Default is US (plain ASCII) */
PENUM(nation, "NATION", nation_names, 0, 2),
PSPECIAL(keymap, "KEYMAP", parsekeymap),
PSPECIAL(keymap, "KEYBOARD", parsekeymap),
#if 0
PRESET(T_STRING, nation, "NATION", NULL),
PRESET(T_STRING, keymap, "KEYMAP", NULL),
PRESET(T_STRING, keymap, "KEYBOARD", NULL),
#endif
LPARSE(T_TOGGLE, slow, "-slow", NULL, 0),
/*Added RKNOP 940328*/
/* Keypad mode */
PENUM(applkeypad, "KEYPAD", keypad_names, KEYP_NUMERIC, 2),
PARSE(T_FLAG, applkeypad, "-numeric", NULL, KEYP_NUMERIC),
PARSE(T_FLAG, applkeypad, "-application", NULL, KEYP_APPL),
/*end added RKNOP 940328*/
/* Cursor style, see "dispmacros.h" */
PENUM(visual, "CURSOR", cursor_names, CUR_BLOCK, 1),
PARSE(T_FLAG, visual, "-ic", NULL, 2),
/* stripping */
PARSE(T_TOGGLE, pass8, "7", "PASS8", 1),
PRESET(T_FLAG, altismeta, "ALTISMETA", 0),
PARSE(T_TOGGLE, invert, "v", "INVERSE", 0),
PENUM(mouse, "MOUSE", mouse_names, 0, 0),
PRESET(T_FLAG, backspace, "BACKSPACE2DELETE", 0),
PRESET(T_FLAG, delete, "DELETE2BACKSPACE", 0),
PRESET(T_FLAG, ctrl8bit, "CTRL8BIT", 0),
PRESET(T_FLAG, blink, "CURSORBLINK", 0),
PARSE(T_STRING, device, "d", "DEVICE", "serial.device"),
PARSE(T_NUMBER, unit, "u", "UNIT", 0),
PARSE(T_NUMBER, dnetwork, "N", NULL, 0),
PARSE(T_NUMBER, bps, "B", "LINESPEED", 38400),
LPARSE(T_FLAG, shared, "-shared", NULL, 1),
LPARSE(T_FLAG, stdio, "-stdio", NULL, 1),
/* The telnet server port */
PARSE(T_STRING, service, "s", "SERVICE", "telnet"),
/* LPARSE(T_FLAG, telnet, "telnet", NULL, 1), */
/* This won't change the prefs structure */
PSPECIAL(emulation, "HOST", addhost),
PARSE(T_STRING, remotename, "r", "REMOTENAME", NULL),
PRESET(T_STRING, remoteterm, "REMOTETYPE", NULL),
/* bell type */
PENUM(bell_type, "BELL", bell_names, BELL_VISUAL, 1),
PARSE(T_TOGGLE, col80, "-80", "FIXEDCOLUMNS", 0),
/* sizing gadget */
PENUM(size_gadget, "SIZEGADGET", sizing_names, SIZE_COLUMN, 1),
PARSE(T_STRING, title, "p", "TITLE", NULL),
PARSE(T_STRING, geometry, "g", "GEOMETRY", NULL),
PARSE(T_STRING, pubscname,"S", "PUBSCREENNAME", NULL),
PARSE(T_STRING, basefont, "f", "BASEFONT", DEFAULTFONTDEF),
{T_END}
};
/*
* show options
*/
static void usage(void)
{
/* puts(version); */
/* puts(copyright); */
PutStr("Usage: " PROGNAME " [-option ...]\n"
"Available " PROGNAME " options are:\n"
" -V show version number & copyright notice\n"
" --h19 emulate an h19 instead of a vt102 terminal\n"
" --vt52 emulate a vt52 on startup\n"
" --vt102 emulate a vt102 on startup (default emulation)\n"
" -l <file> write all output to a log file\n"
" --slow start up in slow mode\n"
" --ic start up with invisible cursor\n"
" --numeric use numeric keypad\n"
" --application use application keypad\n"
" -w wait after program ends before closing window\n"
" -d <devicename> specify device to use (e.g. serial.device)\n"
" -u <unit #> specify unit number to use (see -d)\n"
" -B <linespeed> specify line speed to use\n"
" --shared open device in shared mode\n"
" --stdio take input from stardard input.\n"
" -N <net> specify DNet network number\n"
" -s <service> specify TCP service name\n"
" -r <username> specify remote user name to use\n"
" -7 strip 8th bit of character codes\n"
" -S <screen> specify public screen name\n"
" --80 set to fixed 80 columns\n"
" -f <font>/<size> set the name and size of the default font\n"
" -p <name> set the program name\n"
" -g <l>/<t>/<w>/<h> set up window geometry.");
exit(1);
}
/*
* Set default values
*/
static void preset(void)
{
const struct parsing *p;
hostc = 0;
for (p = presets; p->p_type != T_END; p++) {
if (p->p_resource) {
void *what = NP_ADDR(p->p_offset);
switch (p->p_type) {
case T_STRING:
case T_NUMBER:
*(long*)what = p->p_default;
break;
case T_FLAG:
case T_TOGGLE:
case T_ENUM:
*(char*)what = p->p_default;
break;
}
}
}
}
/*
* `secure' strdup that removes the LF
*/
static char *pstrdup(char *s)
{
char *val;
int size = 0;
while (s[size] && s[size] != '\n')
size++;
val = malloc(size + 1);
if (!val) {
fatalError(MEMORY_ERROR_MSG);
}
memcpy(val, s, size);
val[size] = '\0';
return val;
}
/*
* Add a new host to hosts structure
*/
static void addhost(char *newhost, void *dummy)
{
if (hostc < MAXHOSTS) {
hostarray[hostc++] = newhost;
while (*newhost) {
if (*newhost++ == '|') {
newhost[-1] = '\0';
if (hostc < MAXHOSTS) {
hostarray[hostc++] = newhost;
} else {
break;
}
}
}
} else {
free(newhost);
}
}
/*
* Parse a preset entry from icon or from preset file
*/
static void parse_entry(const char *preset, char *value)
{
const struct parsing *p;
for (p = presets; p->p_type != T_END; p++) {
if (p->p_resource == NULL || strcmp(p->p_resource, preset))
continue;
switch (p->p_type) {
case T_STRING:
*(char**)NP_ADDR(p->p_offset) = pstrdup(value);
break;
case T_NUMBER:
if (StrToLong(value, (long*)NP_ADDR(p->p_offset)) <= 0) {
perrorparse("Expected number for option %s", p->p_resource);
}
break;
case T_FLAG:
case T_TOGGLE:
if (*value == '0' ||
*value == 'n' ||
(*value == 'o' && value[1] == 'f') ||
*value == 'f')
*(char*)NP_ADDR(p->p_offset) = 0;
else
if (*value == '\0' ||
*value == '1' ||
*value == 'y' ||
(*value == 'o' && value[1] == 'n') ||
*value == 't')
*(char*)NP_ADDR(p->p_offset) = 1;
break;
case T_SPECIAL:
/* Call the special function */
p->p_func(pstrdup(value), NP_ADDR(p->p_offset));
break;
case T_ENUM:
{
/*
* Find which token is given
*/
int e;
const char *t = p->p_values;
char *n = value;
/* NUL-terminate */
while (*n && *n != '\n')
n++;
*n = '\0';
for (e = 0; *t; e++) {
if (p->p_slen ?
!Strnicmp(t, value, p->p_slen) :
!Stricmp(t, value)) {
/* Found */
*(char*)NP_ADDR(p->p_offset) = e;
break;
}
while (*t++)
;
}
if (!*t)
perrorparse("Illegal value %s for option %s", value, p->p_resource);
}
break;
}
break; /* for () */
}
if (p->p_type == T_END) {
perrorparse("Unknown option %s", preset);
}
}
/*
* Parse preset file
*/
static void parsepreset(char *myname, char *filename)
{
char *s, *preset, buf[256];
BPTR fh;
while (*filename) {
if (fh = Open(filename, MODE_OLDFILE))
break;
filename += strlen(filename) + 1;
}
if (!*filename)
return;
buf[255] = '\0';
while (FGets(fh, buf, sizeof(buf)-1)) {
/* Comment? */
if (!isalnum(buf[0]))
continue;
for (preset = s = buf; *s; s++) {
if (*s == ':')
break;
else if (islower(*s))
*s += 'A' - 'a';
else if (*s == '.') {
preset = s + 1;
/* Is the program name correct? */
if (strncmp(myname, buf, s - buf))
goto not_for_me;
}
}
if (*s) {
*s++ = '\0';
while (isspace(*s))
s++;
parse_entry(preset, s);
}
not_for_me:
;
}
Close(fh);
return;
}
char **parseargs(char **argv)
{
char *cont;
const struct parsing *p;
char progname[128];
strncpy(progname, FilePart(argv[0]), sizeof(progname));
for (cont = progname; *cont; cont++) {
if (islower(*cont))
*cont += 'A' - 'a';
}
preset();
parsepreset(progname, PREFSFILE);
for (argv = argv + 1; *argv != NULL; argv++) {
if (**argv == '-') {
/* '-' ends options */
if ((*argv)[1] == '\0')
return argv + 1;
cont = *argv + 1;
for (p = presets; p->p_type != T_END; p++) {
if (p->p_type < T_SPECIAL &&
p->p_option &&
!strncmp(p->p_option, cont, p->p_slen)) {
void *what = NP_ADDR(p->p_offset);
switch (p->p_type) {
case T_STRING:
case T_NUMBER:
cont = *++cont ? cont : *(++argv);
if (!cont) usage();
if (p->p_type == T_NUMBER)
StrToLong(cont, (long *)what);
else
*(char **)what = cont;
break;
case T_FLAG:
*(char *)what = p->p_default;
break;
case T_TOGGLE:
*(char *)what = !p->p_default;
break;
}
break;
}
}
/* Didn't found the option? */
if (p->p_type == T_END) usage();
} else {
break;
}
}
return argv;
}
/*
* Workbench setup
*/
static void parseicon(UBYTE *name)
{
struct DiskObject *dobj;
char **toolarray;
char *s, buf[256];
if (!name)
return;
if (dobj = GetDiskObjectNew(name)) {
for (toolarray = (char **)dobj->do_ToolTypes;
toolarray && *toolarray;
toolarray++) {
s = strncpy(buf, *toolarray, sizeof(buf));
buf[sizeof(buf) - 1] = '\0';
while (*s && *s != '=')
s++;
if (*s)
*s++ = '\0';
parse_entry(buf, s);
}
/* Free the diskobject we got */
FreeDiskObject(dobj);
} else {
addhost(pstrdup(name), NULL);
}
}
char **parsewbargs(struct WBStartup *argmsg)
{
LONG i;
struct WBArg *wb_arg_list = argmsg->sm_ArgList;
preset();
for (i = 0; i < argmsg->sm_NumArgs; i++, wb_arg_list++) {
if (wb_arg_list->wa_Lock) {
/* change to the proper directory */
BPTR olddir = CurrentDir(wb_arg_list->wa_Lock) ;
/* process the file */
parseicon(wb_arg_list->wa_Name);
/* change back to the original directory when done */
CurrentDir(olddir) ;
} else {
/* something that does not support locks */
parseicon(wb_arg_list->wa_Name);
}
}
hostarray[hostc] = NULL;
return hostarray;
}
#include <stdarg.h>
#if 0
/*
* Print parse error
*/
void perrorparse(char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vfprintf(stderr,fmt, va);
va_end(va);
fputc('\n', stderr);
}
#else
void perrorparse(char *fmt, ...)
{
}
#endif
/*
* Setup menu items show their current value
*/
#define SETUP_ITEMS 15
struct setup_menu_item setup_items[SETUP_ITEMS + 1] =
{
{
OFFSET_OF(national), 3,
"National Mode",
national_names,
change_national
},
{
OFFSET_OF(nation), 8,
"Nation",
nation_names,
change_nation
},
{
OFFSET_OF(emulation), 3,
"Terminal Type",
emulation_names,
NULL
},
{
OFFSET_OF(ctrl8bit), 2,
"Control Codes",
"7 bit" NUL "8 bit" NUL,
NULL
},
{
OFFSET_OF(backspace), 2,
"Backspace is sent as",
"Backspace" NUL "Delete" NUL,
NULL
},
{
OFFSET_OF(delete), 2,
"Del is sent as",
"Delete" NUL "Backspace" NUL,
NULL
},
{
OFFSET_OF(altismeta), 2,
"Left Alt key is ",
"Alt" NUL "Meta" NUL,
NULL
},
{
/* Added RKNOP 940328 */
OFFSET_OF(applkeypad), 2,
"Keypad",
"Numeric" NUL "Application" NUL,
NULL
},
{
OFFSET_OF(mouse), 4,
"Mouse Events",
mouse_names,
NULL
},
{
OFFSET_OF(visual), 3,
"Cursor",
cursor_names,
change_cursor
},
{
OFFSET_OF(col80), 2,
"Display Width",
"Variable" NUL "80 Columns" NUL,
change_mode80
},
{
OFFSET_OF(slow), 2,
"Display Speed",
"Fast" NUL "Slow" NUL,
NULL
},
{
OFFSET_OF(bell_type), 5,
"Bell Type",
bell_names,
NULL
},
{
OFFSET_OF(invert), 2,
"Reverse",
NULL,
change_invert
},
/* added RKNOP 940328 */
{
OFFSET_OF(ansi_LNM), 2,
"ansi_LNM",
NULL,
change_ansi_LNM
},
/* end added RKNOP 940328 */
{ 0 }
};
int getsetup(unsigned int n)
{
return ((UBYTE*)&np)[setup_items[n].offset];
}
/*
* Change setup menu item n, return new value
*
* If new value is illegal, won't call toggle function
*/
int changesetup(unsigned int n, int val)
{
UBYTE *vp = ((UBYTE*)&np) + setup_items[n].offset;
if (n >= SETUP_ITEMS)
return -1;
if (val >= 0 && val < setup_items[n].choices && *vp != val) {
*vp = val;
if (setup_items[n].change_f)
setup_items[n].change_f(val);
}
return *vp;
}
#if 0
int
main(int argc, char **argv)
{
char **argv2 = parseargs(argv + 1);
printpresets();
if (*argv2) {
puts(*argv2);
}
return 0;
}
#endif